package com.zl.learning.thread.atomic;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

public class AtomicReferenceTest {

    static class User implements Cloneable {
        private String name;
        private Integer age;
        private AtomicInteger score = new AtomicInteger(0);

        public User(String name, Integer age) {
            this.name = name;
            this.age = age;
        }

        public User incrementAge() {
            this.age++;
            return this;
        }

        @Override
        public User clone() {
            try {
                return (User) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        public String toString() {
            return String.format("User{name:%s,age:%d,score:%d}", name,age,score.get());
        }
    }

    private static final AtomicReference<User> AUTOMIC_USER = new AtomicReference<>(new User("zhangsan", 0));
    private static final AtomicInteger INTEGER = new AtomicInteger(0);
    private static final User USER = new User("zhangsan", 0);
    private static final Object LOCK = new Object();

    public static void main(String[] args) {
        final ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            executorService.execute(() -> {
                for (int j = 0; j < 1000; j++) {
                    while (true) {
                        final User user = AUTOMIC_USER.get();
                        User u2 = user.clone();
                        u2.incrementAge();
                        final boolean b = AUTOMIC_USER.compareAndSet(user, u2);
                        if (b) {
                            break;
                        }
                    }
//                    AUTOMIC_USER.updateAndGet(User::incrementAge);
                    USER.score.incrementAndGet();
                    INTEGER.incrementAndGet();
//                    synchronized (LOCK) {
//                        USER.incrementAge();
//                    }
                }
            });
        }
        executorService.shutdown();
        while (!executorService.isTerminated()) {

        }
        System.out.println(AUTOMIC_USER.get());
        System.out.println(INTEGER.get());
        System.out.println(USER);
    }
}
